package com.example.vue.account.service.impl;

import com.auth0.jwt.JWT;
import com.example.vue.account.domain.Account;
import com.example.vue.account.mapper.AccountMapper;
import com.example.vue.account.service.AccountService;
import com.example.vue.account.util.AccountUtil;
import com.example.vue.account.vo.AccountLoginFormVo;
import com.example.vue.account.vo.AccountRegFormVo;
import com.example.vue.comm.domain.PageBean;
import com.example.vue.comm.domain.ResultData;
import com.example.vue.comm.util.CollectionUtil;
import com.example.vue.comm.util.StringUtil;
import com.example.vue.comm.util.WebUtil;
import com.example.vue.jwt.util.JwtUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 账户管理业务逻辑层
 *
 * @author zhouxl
 * @DATE 2020/11/27
 * @descriptoin
 */
@Component
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Override
    public ResultData register(AccountRegFormVo vo) throws NoSuchAlgorithmException {
        ResultData result = ResultData.success("注册成功");
        /*
        1.传过来的数据
            邮箱，密码
        2.业务流程
            2.1.校验基础信息是否合法
            2.2.校验邮箱是否被注册过
         */
        Account account = accountMapper.queryEmail(vo.getEmail());
        if (!Objects.isNull(account)) {
            result.setCode(400);
            result.setMessage("注册失败,当前邮箱已经被注册过!");
            return result;
        }
        account = createRegAccount(vo);
        int update = accountMapper.addAccount(account);
        result.setMessage("注册成功");
        return result;
    }

    @Override
    public ResultData login(AccountLoginFormVo vo, HttpServletResponse response) throws NoSuchAlgorithmException {
        /*
        1.验证验证码
        2.验证用户存在
        3.验证密码
         */
        String code = vo.getCode();
        if (StringUtil.isEmpty(code)) {
            return ResultData.error("无效验证码");
        }
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        ServletContext servletContext = request.getServletContext();
        String ip = WebUtil.getIpAddr(request);
        String sessionCode = (String) (servletContext.getAttribute(ip));
        if (StringUtil.isEmpty(sessionCode)) {
            return ResultData.error("验证码已过期,请重新刷新验证后,再登录");
        }
        Account account = accountMapper.queryEmail(vo.getEmail());
        if (Objects.isNull(account)) {
            return ResultData.error("登录失败,不存在该用户信息");
        }
        String pass = StringUtil.MD5(vo.getPassword(), account.getSalt());
        if (!pass.equals(account.getPassword())) {
            return ResultData.error("登录失败,账户密码不对");
        }

        Map<String, Object> accountInfo = new HashMap<>();
        accountInfo.put("accountNo", account.getAccountNo());
        accountInfo.put("username", account.getUsername());
        accountInfo.put("password", account.getPassword());

        // 设置token信息
        String token = JwtUtil.createJWT(1000 * 60 * 30, accountInfo);

        Map<String, Object> result = new HashMap<>();
        // 清空敏感信息data
        account.setPassword(null);
        ResultData data = ResultData.success(null);
        result.put("token", token);
        result.put("accountData", account);
        result.put("indexPath", "/goods/Goods");
        data.setData(result);
        data.setMessage("登录成功");
        return data;
    }

    @Override
    public Object queryAccountList(Map<String, Object> params) {
        ResultData success = ResultData.success(null);
        int pageNum = Integer.parseInt((String) params.get("page"));
        int limit = Integer.parseInt((String) params.get("limit"));
        PageHelper.startPage(pageNum, limit);
        Page page = accountMapper.queryAccountList(params);
        PageBean pageBean = new PageBean(page);
        success.setData(pageBean);
        return success;
    }

    @Override
    public Object saveAccount(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        // 通过编号查询用户信息是否存在
        Map<String, Object> account = accountMapper.queryAccount(params);
        if (Objects.isNull(account)) {
            data.setCode(400);
            data.setMessage("编辑失败,编辑的当前用户不存在");
            return data;
        }

        // 编辑用户信息
        params.put("updateTime", new Date());
        int row = accountMapper.updateAccount(params);
        data.setMessage("编辑成功");
        return data;
    }

    @Override
    public Object deleteAccount(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        // 删除用户相关的权限信息
        int row = 0;
        row = accountMapper.deleteAccountMenu(params);
        row = accountMapper.deleteAccount(params);
        data.setMessage("删除成功");
        return data;
    }

    @Override
    public Object resetPassAccount(Map<String, Object> params) throws Exception {
        ResultData data = ResultData.success(null);
        String pass = "123456";
        String salt = AccountUtil.getSalt(6);
        String password = StringUtil.MD5(pass, salt);
        params.put("password", password);
        params.put("salt", salt);
        int row = accountMapper.resetPassAccount(params);
        data.setMessage("密码重置成功,密码为:123456");
        return data;
    }

    @Override
    public Object queryAccountMenu(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        // 查询当前用户所有的权限信息
        List<Map<String, Object>> menuList = accountMapper.queryAccountMenu(params);
        // 获取选中的的菜单信息
        List<Object> checkNum = menuList.stream()
                .filter(x -> (long) x.get("flag") == 1)
                .map(x -> x.get("menuNo"))
                .collect(Collectors.toList());
        // 前端的层级树结构信息
        List<Map<String, Object>> subMenuList = new ArrayList<>();
        subAccountMenu(menuList, subMenuList, 1);
        // selectMenu，expandMenu
        Map<String, Object> result = new HashMap<>();
        result.put("selectMenu", checkNum);
        result.put("expandMenu", subMenuList);
        data.setData(result);
        return data;
    }

    @Override
    public Object saveAccountMenu(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        String menuNos = (String) params.get("menuNos");
        String[] menuNoArray = menuNos.split(",");
        int row = accountMapper.deleteAccountMenu(params);
        if (StringUtil.isEmpty(menuNos)) {
            data.setCode(300);
            data.setMessage("保存成功!警告信息:并未选择菜单节点,默认取消该用户所有权限信息");
            return data;
        }
        for (int i = 0; i < menuNoArray.length; i++) {
            params.put("id", StringUtil.uuid());
            params.put("menuNo", menuNoArray[i]);
            row = accountMapper.saveAccountMenu(params);
        }
        data.setMessage("保存成功");
        return data;
    }

    @Override
    public Object changeAccountGender(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        params.put("gender", Integer.parseInt((String) params.get("gender")));
        int row = accountMapper.changeAccountGender(params);
        data.setMessage(row != 0 ? "保存成功" : "保存失败");
        data.setCode(row != 0 ? 200 : 400);
        return data;
    }

    @Override
    public Object changeAccountStatus(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        params.put("status", Integer.parseInt((String) params.get("status")));
        int row = accountMapper.changeAccountStatus(params);
        data.setMessage(row != 0 ? "保存成功" : "保存失败");
        data.setCode(row != 0 ? 200 : 400);
        return data;
    }

    @Override
    public Object queryAccountLeftNavMenu(Map<String, Object> params) {
        ResultData success = ResultData.success(null);
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        String token = request.getHeader("token");
        String accountNo = JWT.decode(token).getClaim("accountNo").asString();
        params.put("accountNo", accountNo);

        List<Map<String, Object>> levelMenuTree = new ArrayList<>();
        // 查询当前用户所有的权限信息
        List<Map<String, Object>> menuList = accountMapper.queryAccountMenu(params);
        menuList = menuList.stream()
                .filter(x -> (long) x.get("flag") == 1)  // 筛选出有效的节点
                .collect(Collectors.toList());
        subAccountMenu(menuList, levelMenuTree, 1);
        if (!CollectionUtil.isEmpty(levelMenuTree)) {
            levelMenuTree = (List<Map<String, Object>>) levelMenuTree.get(0).get("treeList");
        }
        success.setData(levelMenuTree);
        return success;
    }

    @Override
    public Object loginout(Map<String, Object> params) {
        ResultData data = ResultData.success(null);
        String token = (String) params.get("token");
        /*
        清除该用户下所有在服务器下的信息
         */
        return data;
    }

    /**
     * 构建层级的树机构信息
     * 例子
     * 1
     * 2
     * 6
     * 3
     * 4
     * 5
     *
     * @param menuList
     * @param subMenuList
     * @param grade
     */
    private void subAccountMenu(List<Map<String, Object>> menuList, List<Map<String, Object>> subMenuList, int grade) {
        if (Objects.isNull(menuList) || menuList.size() == 0) {
            return;
        }
        if (grade == 1) {   // root节点层级
            Iterator<Map<String, Object>> it = menuList.iterator();
            while (it.hasNext()) {
                Map<String, Object> next = it.next();
                int curGrade = (int) next.get("grade");
                if (curGrade == grade) {
                    subMenuList.add(next);
                    it.remove();
                }
            }
            subAccountMenu(menuList, subMenuList, grade + 1);
        } else {
            for (Map<String, Object> map : subMenuList) {
                String menuNo = (String) map.get("menuNo");
                Iterator<Map<String, Object>> it = menuList.iterator();
                List<Map<String, Object>> subList = new ArrayList<>();
                while (it.hasNext()) {
                    Map<String, Object> next = it.next();
                    String nextPmenuNo = (String) next.get("pMenuNo");
                    if (menuNo.equals(nextPmenuNo)) {
                        subList.add(next);
                        it.remove();
                    }
                }
                map.put("treeList", subList);
                subAccountMenu(menuList, subList, grade + 1);
            }
        }
    }


    /**
     * 创建注册的账户信息
     *
     * @return
     */
    public Account createRegAccount(AccountRegFormVo vo) throws NoSuchAlgorithmException {
        String email = vo.getEmail();
        String pass = vo.getPass();
        String salt = StringUtil.randomStr(6);
        Account account = new Account();
        account.setAccountNo(StringUtil.uuid());
        account.setUsername("新用户" + StringUtil.randomStr(6));
        account.setSalt(salt);
        account.setPassword(StringUtil.MD5(pass, salt));
        account.setGender(0);
        account.setPhone("");
        account.setEmail(email);
        account.setCreateTime(new Date());
        account.setUpdateTime(new Date());
        account.setStatus(0);
        account.setAccountImg("用户图片信息");
        return account;
    }


}
